<?php
class Database
{
        protected $connection = null;

        public function __construct()
        {
                try {
                        $this->connection = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_DATABASE_NAME);

                        if (mysqli_connect_errno()) {
                                throw new Exception("Could not connect to database.");
                        }
                } catch (Exception $e) {
                        throw new RuntimeException($e->getMessage());
                }
        }
        // 魔术方法：当对象被当作字符串时自动调用
        public function __toString()
        {
                return "Database{host: '" . DB_HOST . "', username: '" . DB_USERNAME . "', password: '" . DB_PASSWORD . "',\n database: '" . DB_DATABASE_NAME . "', conn: " . ($this->connection ? 'true' : 'false') . "}";
        }

        public function select($query = "", $params = [])
        {
                try {
                        $stmt = $this->executeStatement($query, $params);
                        $result = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
                        $stmt->close();

                        return $result;
                } catch (Exception $e) {
                        throw new RuntimeException($e->getMessage());
                }
        }

        public function execute($query = "", $params = [])
        {
                try {
                        error_log("执行SQL语句: " . $query . "\n");
                        error_log("参数: " . implode(", ", $params) . "\n");
                        $stmt = $this->executeStatement($query, $params);
                        error_log("新数据插入成功，新记录ID: " . $stmt->insert_id . "\n");
                        $stmt->close();
                        return true;
                } catch (Exception $e) {
                        throw new RuntimeException($e->getMessage());
                }
        }
        /**
         * 使用位置占位符
         * @param mixed $query
         * @param mixed $params
         * @throws \Exception
         * @return bool|mysqli_stmt
         */
        private function executeStatement($query = "", $params = [])
        {
                try {
                        $stmt = $this->connection->prepare($query);

                        if ($stmt === false) {
                                throw new RuntimeException("Unable to do prepared statement: " . $query);
                        }

                        if (!empty($params)) {
                                // 生成类型定义字符串（根据参数类型自动生成）
                                $types = '';
                                foreach ($params as $param) {
                                        if (is_int($param)) {
                                                $types .= 'i';  // 整数
                                        } elseif (is_float($param)) {
                                                $types .= 'd';  // 浮点数
                                        } elseif (is_string($param)) {
                                                $types .= 's';  // 字符串
                                        } else {
                                                $types .= 'b';  // 二进制
                                        }
                                }

                                // 绑定参数：类型字符串长度必须 = 参数数量
                                // 使用 ... 运算符展开参数数组
                                $stmt->bind_param($types, ...$params);
                        }
                        $stmt->execute();
                        // error_log("执行SQL语句成功: " . $query . "\n");
                        // error_log("参数: " . implode(", ", $params) . "\n");
                        // error_log("影响行数: " . $stmt->affected_rows . "\n");
                        return $stmt;
                } catch (Exception $e) {
                        throw new Exception($e->getMessage());
                }
        }
}
